﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;
using Chemistry.Models;
using OPCAutomation;

namespace Chemistry.WorkFlow
{
    using System.Text;

    /// <summary>
   /// 分步骤考核基类
   /// </summary>
    public class FlowBaseStep:FlowBaseAll
    {
        #region 字段
        //步骤记录
        protected List<ExaminationPoint> _points;
        protected Dictionary<string, StepDescription> _dicSteps;
        protected int _sleepfast = 500;
        #endregion

        #region 构造函数
        public FlowBaseStep()
        {
            _listenCts = new CancellationTokenSource();
            _dicSteps = new Dictionary<string, StepDescription>();
            _points = new List<ExaminationPoint>();
        } 
        #endregion

        #region 公共方法
     
       protected override int CalcScore()
       {
           double sumscore = 0;
           StringBuilder builder = new StringBuilder();
           var count = _dicSteps.Keys.Count;
           double stepscore = Math.Round((double)(100 / count ), 2);
           int index = 1;
           foreach (var step in _dicSteps.Values)
           {
               string temp = String.Empty;
               if (step.IsRight)
               {
                   sumscore += stepscore;
                   temp = String.Format("{0}. {1}\t分值：{2}",index, step.Description, stepscore);
               }
               else
               {
                   temp = String.Format("{0}. {1}\t分值：{2}", index, step.Description, 0);
               }
               index++;
               builder.AppendLine(temp);
           }
           Content = builder.ToString();
           return (int)Math.Round(sumscore, 0);
       }
        #endregion



        #region Protect 添加步骤
        /// <summary>
        /// 添加范围值步骤
        /// </summary>
        /// <param name="stepName">步骤名称</param>
        /// <param name="valueName">值名称（液位，压力，温度）</param>
        /// <param name="stepItem">步骤</param>
        /// <param name="statusName">枚举名称</param>
       protected void InsertRangeValueStep(string stepName, ValueName valueName, Step stepItem, Enum statusName)
        {
            var step = _points.SingleOrDefault(i => i.Description == stepName);
            if (step.IsChecked)
            {
                if (stepItem != null)
                {
                    var value = stepItem.Status[statusName];
                    this.SetStepDescription(stepName, valueName, value, step);
                }
                else
                {
                    if (_dicSteps.Keys.Contains(stepName))
                    _dicSteps[stepName]= new StepDescription() { Description = step.Description + "，无操作", IsRight = false };
                    else
                        _dicSteps.Add(stepName, new StepDescription() { Description = step.Description + "，无操作", IsRight = false });
                }
            }
        }


        /// <summary>
        /// 添加范围步骤
        /// </summary>
        /// <param name="stepName">步骤名称</param>
        /// <param name="valueName">值名称（液位，压力，温度）</param>
        /// <param name="value">具体值</param>
        protected void InsertRangeValueStep(string stepName, ValueName valueName, double value)
        {
            var step = _points.SingleOrDefault(i => i.Description == stepName);
            if (step.IsChecked)
            {
                if (value != -1)
                {
                    this.SetStepDescription(stepName, valueName, value, step);
                }
                else
                {
                    if (_dicSteps.Keys.Contains(stepName))
                        _dicSteps[stepName]= new StepDescription() { Description = step.Description + "，无操作", IsRight = false };
                    else
                        _dicSteps.Add(stepName, new StepDescription() { Description = step.Description + "，无操作", IsRight = false });
                }
            }
        }

        private void SetStepDescription(string stepName, ValueName valueName, double value, ExaminationPoint step)
        {
            if (value >= step.Value1 && value <= step.Value2)
            {
                //步骤名称：压力1，在0-2范围内
                string temp = string.Format("{0}:{1}{2},在{3}-{4}范围内", stepName, valueName, value, step.Value1, step.Value2);
                if (_dicSteps.Keys.Contains(stepName))
                    _dicSteps[stepName] = new StepDescription() { Description = temp, IsRight = true };
                else 
                    this._dicSteps.Add(stepName, new StepDescription() { Description = temp, IsRight = true });
            }
            else
            {
                string temp = string.Format("{0}:{1}{2},不在{3}-{4}范围内", stepName, valueName, value, step.Value1, step.Value2);
                if (_dicSteps.Keys.Contains(stepName))
                    _dicSteps[stepName] = new StepDescription() { Description = temp, IsRight = false };
                else
                    this._dicSteps.Add(stepName, new StepDescription() { Description = temp, IsRight = false });
            }
        }

        /// <summary>
        /// 添加动作步骤
        /// </summary>
        /// <param name="stepName">步骤名称</param>
        /// <param name="stepItem">步骤item</param>
        protected void InsertActionStep(string stepName, Step stepItem)
        {
            var step = _points.SingleOrDefault(i => i.Description == stepName);
            if (step.IsChecked)
            {
                if (_dicSteps.Keys.Contains(step.Description))
                    _dicSteps[stepName] = stepItem != null
                        ? new StepDescription() { Description = step.Description + "，完成", IsRight = true }
                        : new StepDescription() { Description = step.Description + "，未操作", IsRight = true };
                else

                this._dicSteps.Add(
                    step.Description,
                    stepItem != null
                        ? new StepDescription() { Description = step.Description + "，完成", IsRight = true }
                        : new StepDescription() { Description = step.Description + "，未操作", IsRight = true });
            }
        }
        #endregion


        #region 触发异常 
        protected DateTime _leakAbnormalDate;
        protected DateTime _pressureAbnormalData;
        protected DateTime _temperatureAbnormalDate;
        private int _loopcount = 0;
        protected void CheckAbnormalPoint()
        {
            var pressureAbnormal = _points.SingleOrDefault(i => i.Description == "压力突变异常");
            var leakAbnormal = _points.SingleOrDefault(i => i.Description == "泄漏异常");
            var temperatureAbnormal = _points.SingleOrDefault(i => i.Description == "温度突变异常");
            //压力异常
            if (pressureAbnormal!=null && pressureAbnormal.IsChecked)
            {
                Task.Run(
                    () =>
                    {
                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (_loopcount == 240) //2分钟
                            {
                                this.BeginPressureAbnormal(pressureAbnormal.Value1);
                                break;
                            }
                            Thread.Sleep(_sleepfast);
                        }
                    });
            }
            //温度异常
            if (temperatureAbnormal!=null&&temperatureAbnormal.IsChecked)
            {
                Task.Run(
                    () =>
                    {
                        while (!_listenCts.IsCancellationRequested)
                        {
                            if (_loopcount == 240) //2分钟
                            {
                                this.BeginTempretureAbnormal(temperatureAbnormal.Value1);
                                break;
                            }
                            Thread.Sleep(_sleepfast);
                        }
                    });
            }
            //泄漏
            if (leakAbnormal!=null&&leakAbnormal.IsChecked)
            {
                Task.Run(
                   () =>
                   {
                       while (!_listenCts.IsCancellationRequested)
                       {
                           if (_loopcount == 240) //2分钟
                           {
                               this.BeginLeakAbnormal();
                               break;
                           }
                           Thread.Sleep(_sleepfast);
                       }
                   });
            }

        }

        protected virtual void BeginLeakAbnormal(){}
        protected virtual void BeginTempretureAbnormal(double value){}
        protected virtual void BeginPressureAbnormal(double value) { }

        #endregion

        //枚举
        /// <summary>
        /// 值名称
        /// </summary>
        protected enum ValueName
        {
            温度, 压力, 比例, 液位, 重量,
            流量
        }
    }

    /// <summary>
    /// 步骤描述类
    /// <remarks>分步考核用，用于记录考试步骤</remarks>
    /// </summary>
    public struct StepDescription
    {
        public string Description { get; set; }
        public bool IsRight { get; set; }
    }
}
